// Copyright 2019 The FlutterCandies author. All rights reserved.
// Use of this source code is governed by an Apache license that can be found
// in the LICENSE file.

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:photo_manager_image_provider/photo_manager_image_provider.dart';
import 'package:video_player/video_player.dart';
import 'package:wechat_picker_library/wechat_picker_library.dart';

import '../../constants/constants.dart';
import '../../delegates/asset_picker_viewer_builder_delegate.dart';
import '../../internals/singleton.dart';
// 导入鸿蒙平台工具和图片提供者
import 'package:photo_manager/platform_utils.dart';
import 'ohos_asset_image_provider.dart';

class VideoPageBuilder extends StatefulWidget {
  const VideoPageBuilder({
    super.key,
    required this.asset,
    required this.delegate,
    this.hasOnlyOneVideoAndMoment = false,
    this.shouldAutoplayPreview = false,
  });

  /// Asset currently displayed.
  /// 展示的资源
  final AssetEntity asset;

  final AssetPickerViewerBuilderDelegate<AssetEntity, AssetPathEntity> delegate;

  /// Only previewing one video and with the [SpecialPickerType.wechatMoment].
  /// 是否处于 [SpecialPickerType.wechatMoment] 且只有一个视频
  final bool hasOnlyOneVideoAndMoment;

  /// Whether the preview should auto play.
  /// 预览是否自动播放
  final bool shouldAutoplayPreview;

  @override
  State<VideoPageBuilder> createState() => _VideoPageBuilderState();
}

class _VideoPageBuilderState extends State<VideoPageBuilder> {
  /// Controller for the video player.
  /// 视频播放的控制器
  VideoPlayerController get controller => _controller!;
  VideoPlayerController? _controller;

  /// Whether the controller has initialized.
  /// 控制器是否已初始化
  bool hasLoaded = false;

  /// Whether there's any error when initialize the video controller.
  /// 初始化视频控制器时是否发生错误
  bool hasErrorWhenInitializing = false;

  /// Whether the player is playing.
  /// 播放器是否在播放
  final ValueNotifier<bool> isPlaying = ValueNotifier<bool>(false);

  /// Whether the controller is playing.
  /// 播放控制器是否在播放
  bool get isControllerPlaying => _controller?.value.isPlaying ?? false;

  bool _isInitializing = false;
  bool _isLocallyAvailable = false;
  bool _showThumbnail = true; // 新增状态：控制是否显示缩略图
  DateTime _lastThumbnailUpdate = DateTime.now(); // 防抖时间戳

  @override
  void didUpdateWidget(VideoPageBuilder oldWidget) {
    super.didUpdateWidget(oldWidget);
    if (widget.asset != oldWidget.asset) {
      _controller
        ?..removeListener(videoPlayerListener)
        ..pause()
        ..dispose();
      _controller = null;
      hasLoaded = false;
      hasErrorWhenInitializing = false;
      isPlaying.value = false;
      _isInitializing = false;
      _isLocallyAvailable = false;
      _showThumbnail = true; // 重置缩略图显示状态
      _lastThumbnailUpdate = DateTime.now(); // 重置防抖时间戳
    }
  }

  @override
  void dispose() {
    /// Remove listener from the controller and dispose it when widget dispose.
    /// 部件销毁时移除控制器的监听并销毁控制器。
    _controller
      ?..removeListener(videoPlayerListener)
      ..pause()
      ..dispose();
    isPlaying.dispose();
    _showThumbnail = false; // 重置缩略图显示状态
    super.dispose();
  }

  /// Get media url from the asset, then initialize the controller and add with a listener.
  /// 从资源获取媒体url后初始化，并添加监听。
  Future<void> initializeVideoPlayerController() async {
    // 鸿蒙平台特殊处理
    if (PlatformUtils.isOhos) {
      debugPrint('开始初始化视频控制器');
      _isInitializing = true;
      // 立即更新UI状态，显示加载指示器
      safeSetState(() {});
      
      try {
        // 先预加载缩略图数据，提高用户体验
        if (PlatformUtils.isOhos) {
          await _preloadThumbnailForOhos();
        }
        
        final String? url = await widget.asset.getMediaUrl();
        debugPrint('获取到视频URL: $url');
        if (url == null) {
          debugPrint('无法获取视频URL');
          hasErrorWhenInitializing = true;
          _isInitializing = false;
          return;
        }
        
        final Uri uri = Uri.parse(url);
        debugPrint('解析URL为Uri: $uri');
        // 针对鸿蒙平台的特殊处理
        if (PlatformUtils.isOhos) {
          debugPrint('鸿蒙平台特殊处理');
          // 鸿蒙平台使用file路径而不是content uri
          _controller = await _loadVideoForOhos(uri);
        } else if (Platform.isAndroid) {
          debugPrint('使用content uri加载视频');
          _controller = VideoPlayerController.contentUri(uri);
        } else {
          debugPrint('使用网络URL加载视频');
          _controller = VideoPlayerController.networkUrl(uri);
        }
        
        debugPrint('开始初始化视频控制器');
        // 添加重试机制和超时处理
        bool initialized = false;
        int retryCount = 0;
        const int maxRetries = 3;
        
        while (!initialized && retryCount < maxRetries) {
          try {
            // 添加超时处理
            final initializeFuture = controller.initialize();
            await initializeFuture.timeout(Duration(seconds: 10));
            initialized = true;
            debugPrint('视频控制器初始化完成');
          } catch (initError) {
            retryCount++;
            debugPrint('视频控制器初始化失败，重试次数: $retryCount, 错误: $initError');
            if (retryCount < maxRetries) {
              await Future.delayed(Duration(milliseconds: 500 * retryCount));
            } else {
              rethrow; // 达到最大重试次数，重新抛出异常
            }
          }
        }
        
        hasLoaded = true;
        _isLocallyAvailable = true;
        _isInitializing = false; // 确保在初始化完成后重置状态
        
        // 不要立即隐藏封面，让封面保持显示直到用户点击播放
        // _updateThumbnailVisibility(false);
        
        // 确保UI更新
        safeSetState(() {});
        
        controller
          ..addListener(videoPlayerListener)
          ..setLooping(widget.hasOnlyOneVideoAndMoment);
          
        if (widget.hasOnlyOneVideoAndMoment || widget.shouldAutoplayPreview) {
          // 自动播放时隐藏封面
          debugPrint('自动播放视频');
          _updateThumbnailVisibility(false);
          controller.play();
        }
      } catch (e, s) {
        debugPrint('视频控制器初始化失败: $e');
        debugPrint('堆栈信息: $s');
        FlutterError.presentError(
          FlutterErrorDetails(
            exception: e,
            stack: s,
            library: packageName,
            silent: true,
          ),
        );
        hasErrorWhenInitializing = true;
        _isInitializing = false;
      } finally {
        safeSetState(() {});
      }
    } else {
      // 安卓和其他平台使用原始逻辑
      _isInitializing = true;
      _isLocallyAvailable = true;
      final String? url = await widget.asset.getMediaUrl();
      if (url == null) {
        hasErrorWhenInitializing = true;
        safeSetState(() {});
        return;
      }
      final Uri uri = Uri.parse(url);
      if (Platform.isAndroid) {
        _controller = VideoPlayerController.contentUri(uri);
      } else {
        _controller = VideoPlayerController.networkUrl(uri);
      }
      try {
        await controller.initialize();
        hasLoaded = true;
        controller
          ..addListener(videoPlayerListener)
          ..setLooping(widget.hasOnlyOneVideoAndMoment);
        if (widget.hasOnlyOneVideoAndMoment || widget.shouldAutoplayPreview) {
          controller.play();
        }
      } catch (e, s) {
        FlutterError.presentError(
          FlutterErrorDetails(
            exception: e,
            stack: s,
            library: packageName,
            silent: true,
          ),
        );
        hasErrorWhenInitializing = true;
      } finally {
        safeSetState(() {});
      }
    }
  }

  /// Listener for the video player.
  /// 播放器的监听方法
  void videoPlayerListener() {
    // 鸿蒙平台特殊处理
    if (PlatformUtils.isOhos) {
      debugPrint('视频播放器状态改变，当前播放状态: ${isControllerPlaying}');
      if (isControllerPlaying != isPlaying.value) {
        isPlaying.value = isControllerPlaying;
        debugPrint('更新播放状态: ${isPlaying.value}');
        // 只有在视频真正开始播放时才隐藏封面
        if (isControllerPlaying) {
          debugPrint('视频开始播放，隐藏封面');
          _updateThumbnailVisibility(false);
        }
      }
    } else {
      // 安卓和其他平台使用原始逻辑
      if (isControllerPlaying != isPlaying.value) {
        isPlaying.value = isControllerPlaying;
      }
    }
  }

  /// Callback for the play button.
  /// 播放按钮的回调
  ///
  /// Normally it only switches play state for the player. If the video reaches the end,
  /// then click the button will make the video replay.
  /// 一般来说按钮只切换播放暂停。当视频播放结束时，点击按钮将从头开始播放。
  Future<void> playButtonCallback(BuildContext context) async {
    // 鸿蒙平台特殊处理
    if (PlatformUtils.isOhos) {
      debugPrint('用户点击播放按钮');
      debugPrint('当前播放状态: ${isPlaying.value}');
      debugPrint('控制器播放状态: $isControllerPlaying');
      
      // 确保隐藏封面
      if (_showThumbnail) {
        debugPrint('隐藏视频封面');
        _updateThumbnailVisibility(false);
      }
      
      if (isPlaying.value) {
        debugPrint('暂停视频播放');
        controller.pause();
        return;
      }
      
      if (widget.delegate.isDisplayingDetail.value &&
          !MediaQuery.accessibleNavigationOf(context)) {
        widget.delegate.switchDisplayingDetail(value: false);
      }
      
      if (controller.value.duration == controller.value.position) {
        debugPrint('视频播放结束，重新播放');
        controller
          ..seekTo(Duration.zero)
          ..play();
        return;
      }
      
      debugPrint('开始视频播放');
      controller.play();
    } else {
      // 安卓和其他平台使用原始逻辑
      if (isPlaying.value) {
        controller.pause();
        return;
      }
      if (widget.delegate.isDisplayingDetail.value &&
          !MediaQuery.accessibleNavigationOf(context)) {
        widget.delegate.switchDisplayingDetail(value: false);
      }
      if (controller.value.duration == controller.value.position) {
        controller
          ..seekTo(Duration.zero)
          ..play();
        return;
      }
      controller.play();
    }
  }

  Widget _contentBuilder(BuildContext context) {
    // 鸿蒙平台特殊处理，确保视频封面完整显示
    if (PlatformUtils.isOhos) {
      return Stack(
        fit: StackFit.expand,
        children: <Widget>[
          // 视频播放器
          if (!_showThumbnail) // 只有在封面隐藏时才显示视频播放器
            Center(
              child: AspectRatio(
                aspectRatio: controller.value.aspectRatio,
                child: VideoPlayer(controller),
              ),
            ),
          // 封面图片（在视频播放前显示），确保使用第一帧并完整显示
          if (_showThumbnail)
            Center(
              child: Image(
                image: PlatformUtils.isOhos 
                  ? OhosAssetEntityImageProvider(
                      widget.asset,
                      isOriginal: false, // 鸿蒙平台使用第一帧作为封面
                      thumbnailSize: const ThumbnailSize(800, 800), // 鸿蒙平台使用更大的缩略图
                      frame: 0, // 使用第一帧作为封面
                    )
                  : AssetEntityImageProvider(
                      widget.asset,
                      isOriginal: false,
                      thumbnailSize: const ThumbnailSize.square(200),
                    ),
                fit: PlatformUtils.isOhos ? BoxFit.contain : BoxFit.cover,
                errorBuilder: (context, error, stackTrace) {
                  // 如果封面图片加载失败，显示默认占位符
                  return Container(
                    color: Colors.black.withOpacity(0.3),
                    child: const Icon(
                      Icons.videocam,
                      color: Colors.white70,
                      size: 50,
                    ),
                  );
                },
              ),
            ),
          // 播放按钮 - 简化逻辑，确保始终正确显示
          ValueListenableBuilder<bool>(
            valueListenable: isPlaying,
            builder: (_, bool value, __) {
              final bool showPlayButton = !value || _showThumbnail;
              return Center(
                child: AnimatedOpacity(
                  duration: kThemeAnimationDuration,
                  opacity: showPlayButton ? 1.0 : 0.0,
                  child: GestureDetector(
                    onTap: () {
                      playButtonCallback(context);
                    },
                    child: DecoratedBox(
                      decoration: const BoxDecoration(
                        boxShadow: <BoxShadow>[
                          BoxShadow(color: Colors.black12),
                        ],
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        value && !_showThumbnail
                            ? Icons.pause_circle_outline
                            : Icons.play_circle_filled,
                        size: 70.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              );
            },
          ),
        ],
      );
    } else {
      // 安卓和其他平台使用原始逻辑
      return Stack(
        fit: StackFit.expand,
        children: <Widget>[
          Positioned.fill(
            child: Center(
              child: AspectRatio(
                aspectRatio: controller.value.aspectRatio,
                child: VideoPlayer(controller),
              ),
            ),
          ),
          if (!widget.hasOnlyOneVideoAndMoment)
            ValueListenableBuilder<bool>(
              valueListenable: isPlaying,
              builder: (_, bool value, __) => GestureDetector(
                behavior: HitTestBehavior.opaque,
                onTap: value || MediaQuery.accessibleNavigationOf(context)
                    ? () {
                        playButtonCallback(context);
                      }
                    : widget.delegate.switchDisplayingDetail,
                child: Center(
                  child: AnimatedOpacity(
                    duration: kThemeAnimationDuration,
                    opacity: value ? 0.0 : 1.0,
                    child: GestureDetector(
                      onTap: () {
                        playButtonCallback(context);
                      },
                      child: DecoratedBox(
                        decoration: const BoxDecoration(
                          boxShadow: <BoxShadow>[
                            BoxShadow(color: Colors.black12),
                          ],
                          shape: BoxShape.circle,
                        ),
                        child: Icon(
                          value
                              ? Icons.pause_circle_outline
                              : Icons.play_circle_filled,
                          size: 70.0,
                          color: Colors.white,
                        ),
                      ),
                    ),
                  ),
                ),
              ),
            ),
        ],
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    // 鸿蒙平台特殊处理
    if (PlatformUtils.isOhos) {
      return LocallyAvailableBuilder(
        key: ValueKey<String>(widget.asset.id),
        asset: widget.asset,
        isOriginal: false,
        builder: (BuildContext context, AssetEntity asset) {
          if (hasErrorWhenInitializing) {
            return Center(
              child: ScaleText(
                Singleton.textDelegate.loadFailed,
                semanticsLabel:
                    Singleton.textDelegate.semanticsTextDelegate.loadFailed,
              ),
            );
          }
          // 检查是否需要初始化视频控制器
          if (!_isLocallyAvailable && !_isInitializing) {
            debugPrint('开始初始化视频控制器');
            // 确保封面显示
            if (!_showThumbnail) {
              _updateThumbnailVisibility(true);
            }
            initializeVideoPlayerController();
          }
          // 始终显示封面，直到视频完全加载完成并且开始播放
          if (!hasLoaded || _showThumbnail) {
            debugPrint('显示视频封面，hasLoaded: $hasLoaded, _showThumbnail: $_showThumbnail');
            // 显示封面图片作为占位符，并添加播放按钮
            return Stack(
              fit: StackFit.expand,
              children: [
                // 在鸿蒙平台上使用特殊的图片提供者来加载视频封面
                if (PlatformUtils.isOhos)
                  Center(
                    child: Image(
                      image: OhosAssetEntityImageProvider(
                        widget.asset,
                        isOriginal: false, // 鸿蒙平台使用第一帧作为封面
                        thumbnailSize: const ThumbnailSize(800, 800), // 鸿蒙平台使用更大的缩略图
                        frame: 0, // 使用第一帧作为封面
                      ),
                      fit: BoxFit.contain,
                      errorBuilder: (context, error, stackTrace) {
                        // 如果封面图片加载失败，显示默认占位符
                        return Container(
                          color: Colors.black.withOpacity(0.3),
                          child: const Icon(
                            Icons.videocam,
                            color: Colors.white70,
                            size: 50,
                        ),
                        );
                      },
                    )
                  )
                else
                  Center(
                    child: Image(
                      image: AssetEntityImageProvider(
                        widget.asset,
                        isOriginal: false,
                        thumbnailSize: const ThumbnailSize.square(200),
                      ),
                      fit: BoxFit.contain,
                      errorBuilder: (context, error, stackTrace) {
                        // 如果封面图片加载失败，显示默认占位符
                        return Container(
                          color: Colors.black.withOpacity(0.3),
                          child: const Icon(
                            Icons.videocam,
                            color: Colors.white70,
                            size: 50,
                          ),
                        );
                      },
                    )
                  ),
                // 只有在初始化过程中才显示加载指示器
                if (_isInitializing && !hasErrorWhenInitializing)
                  const Center(
                    child: CircularProgressIndicator(),
                  ),
                // 添加播放按钮，确保在加载过程中也能看到
                Center(
                  child: GestureDetector(
                    onTap: () {
                      // 如果正在初始化，点击播放按钮时等待初始化完成再播放
                      if (_isInitializing) {
                        // 可以添加提示或忽略点击
                        return;
                      }
                      playButtonCallback(context);
                    },
                    child: DecoratedBox(
                      decoration: const BoxDecoration(
                        boxShadow: <BoxShadow>[
                          BoxShadow(color: Colors.black12),
                        ],
                        shape: BoxShape.circle,
                      ),
                      child: Icon(
                        Icons.play_circle_filled,
                        size: 70.0,
                        color: Colors.white,
                      ),
                    ),
                  ),
                ),
              ],
            );
          }
          // 视频加载完成，显示播放界面
          debugPrint('视频加载完成，显示播放界面');
          debugPrint('播放状态: ${isPlaying.value}, 控制器状态: $isControllerPlaying');
          debugPrint('封面显示状态: $_showThumbnail');
          return Semantics(
            onLongPress: () {
              debugPrint('用户长按视频播放');
              playButtonCallback(context);
            },
            onLongPressHint:
                Singleton.textDelegate.semanticsTextDelegate.sActionPlayHint,
            child: _contentBuilder(context),
          );
        },
      );
    } else {
      // 安卓和其他平台使用原始逻辑
      return LocallyAvailableBuilder(
        key: ValueKey<String>(widget.asset.id),
        asset: widget.asset,
        isOriginal: false,
        builder: (BuildContext context, AssetEntity asset) {
          if (hasErrorWhenInitializing) {
            return Center(
              child: ScaleText(
                Singleton.textDelegate.loadFailed,
                semanticsLabel:
                    Singleton.textDelegate.semanticsTextDelegate.loadFailed,
              ),
            );
          }
          if (!_isLocallyAvailable && !_isInitializing) {
            initializeVideoPlayerController();
          }
          if (!hasLoaded) {
            return const SizedBox.shrink();
          }
          return Semantics(
            onLongPress: () {
              playButtonCallback(context);
            },
            onLongPressHint:
                Singleton.textDelegate.semanticsTextDelegate.sActionPlayHint,
            child: _contentBuilder(context),
          );
        },
      );
    }
  }

  /// 安全更新缩略图显示状态，带防抖机制
  void _updateThumbnailVisibility(bool show) {
    final now = DateTime.now();
    // 防抖：100毫秒内不重复更新
    if (now.difference(_lastThumbnailUpdate).inMilliseconds < 100) {
      return;
    }
    
    _lastThumbnailUpdate = now;
    if (_showThumbnail != show) {
      setState(() {
        _showThumbnail = show;
      });
    }
  }

  /// 鸿蒙平台特殊处理：预加载视频封面
  Future<void> _preloadThumbnailForOhos() async {
    if (!PlatformUtils.isOhos) return;
    
    try {
      // 预加载视频第一帧作为封面以提高加载速度
      final thumbnailData = await widget.asset.thumbnailDataWithOption(
        ThumbnailOption(
          size: const ThumbnailSize.square(800),
          format: ThumbnailFormat.jpeg,
          frame: 0, // 使用第一帧作为封面
        ),
      );
      if (thumbnailData != null) {
        debugPrint('鸿蒙平台预加载视频封面成功');
      }
    } catch (e) {
      debugPrint('鸿蒙平台预加载视频封面失败: $e');
      
      // 添加重试机制
      try {
        await Future.delayed(const Duration(milliseconds: 200));
        final thumbnailDataRetry = await widget.asset.thumbnailDataWithOption(
          ThumbnailOption(
            size: const ThumbnailSize.square(800),
            format: ThumbnailFormat.jpeg,
            frame: 0, // 使用第一帧作为封面
          ),
        );
        if (thumbnailDataRetry != null) {
          debugPrint('鸿蒙平台预加载视频封面重试成功');
        }
      } catch (retryError) {
        debugPrint('鸿蒙平台预加载视频封面重试失败: $retryError');
      }
    }
  }
  
  /// 鸿蒙平台特殊处理：加载视频文件
  Future<VideoPlayerController?> _loadVideoForOhos(Uri uri) async {
    if (!PlatformUtils.isOhos) return null;
    
    try {
      debugPrint('鸿蒙平台尝试加载视频文件');
      final file = await widget.asset.loadFile();
      debugPrint('加载文件: $file');
      
      if (file != null) {
        debugPrint('文件路径: ${file.path}');
        debugPrint('文件是否存在: ${await file.exists()}');
        debugPrint('文件长度: ${await file.length()}');
        
        // 检查文件是否有效
        if (await file.exists() && await file.length() > 0) {
          debugPrint('使用文件路径加载视频: ${file.path}');
          return VideoPlayerController.file(file);
        } else {
          debugPrint('文件无效，尝试使用媒体URL');
          try {
            final mediaUrl = await widget.asset.getMediaUrl();
            if (mediaUrl != null) {
              final mediaUri = Uri.parse(mediaUrl);
              debugPrint('使用媒体URL加载视频: $mediaUrl');
              return VideoPlayerController.networkUrl(mediaUri);
            } else {
              debugPrint('无法获取媒体URL，使用网络URL加载视频');
              return VideoPlayerController.networkUrl(uri);
            }
          } catch (urlError) {
            debugPrint('获取媒体URL失败: $urlError');
            return VideoPlayerController.networkUrl(uri);
          }
        }
      } else {
        debugPrint('文件不存在，使用网络URL加载视频');
        return VideoPlayerController.networkUrl(uri);
      }
    } catch (e) {
      debugPrint('鸿蒙平台加载视频文件失败: $e');
      return VideoPlayerController.networkUrl(uri);
    }
  }
}